package sim.core;

import java.awt.*;

import static sim.core.Network.*;

/**
 * 
 * The base class to extend to create new node types with specific behavior.
 * 
 * @author smd
 *
 */
abstract public class AbstractNode implements MessageHandler {

	protected SoftwareClock myClock ;
	/**
	 * Endpoint that implements the message exchange operations for the node.
	 * Used explicitly to send messages and implicitly when a message is received.
	 * 
	 */
	public EndPoint endpoint ;
	
	protected AbstractNode() {
		endpoint = Network.newEndPoint( this ) ;
		myClock = new SoftwareClock( endpoint.pos ) ;
		setColor( Color.gray ) ;
	}

	protected void putOffline() {
		endpoint.online = false ;
	}
 	
	protected void setMessageHandler( MessageHandler handler ) {
		endpoint.handler = handler;
	}
	/**
	 * Returns the current time in the calling node.
	 * @return The current time in the calling node.
	 */
	public double currentTime() {
		return myClock.currentTime() ;
	}
	
	/**
	 * Set the color used to render the node in the simulator window.
	 * @param c
	 */
	public void setColor( Color c ) {
		endpoint.color = c ;
	}
	
	/**
	 * Returns the current color of the node.
	 * @return The current color of the node.
	 */
	public Color getColor() {
		return endpoint.color ;
	}
	
	/* (non-Javadoc)
	 * @see sim.core.MessageHandler#onSendFailure(sim.core.EndPoint, sim.core.Message)
	 */
	public void onSendFailure( EndPoint dst, Message m ) {}

	
	/* (non-Javadoc)
	 * 
	 * @see sim.core.MessageHandler#onReceive(sim.core.EndPoint, sim.core.Message)
	 */
	public void onReceive( EndPoint src, Message m ) {
		throw new RuntimeException("AbstractNode.onReceive(...): Unhandled Message...") ;
	}
	
	/* (non-Javadoc)
	 * 
	 * @see sim.core.MessageHandler#onReceive(sim.core.TcpChannel, sim.core.Message)
	 */
	public void onReceive( TcpChannel ch, Message m ) {
		throw new RuntimeException("AbstractNode.onReceive(...): Unhandled Message...") ;
	}
	
    /**
     * Method that needs to be overridden.
     * Place all node initialization code here, including the tasks that implement the behavior of the node.
     *  
     */
    public void init() {}

    /**
     * Puts the node offline. This operation is irreversible.
     * Closes and frees the communication endpoint of this node. No further communication can be sent of received from this node.
     * Cancels all tasks owned by this node.
     */
    public void dispose() {
    	endpoint.dispose() ;
    	Scheduler.cancelAll( this ) ;    	
    }

    
}
